<?php

namespace Payment\Trans;

use Payment\Common\PayException;
use Payment\Common\Weixin\Data\PayBankData;
use Payment\Common\Weixin\WxBaseStrategy;
use Payment\Common\WxConfig;
use Payment\Config;
use Payment\Utils\Curl;
use Payment\Utils\DataParser;

/**
 * 微信企业付款到银行卡接口
 * Class WxPayBank
 * @package Payment\Trans
 *
 */
class WxPayBank extends WxBaseStrategy
{

    public function getBuildDataClass()
    {
        return PayBankData::class;
    }

    /*
     * 返回企业付款到银行卡的url
     */
    protected function getReqUrl()
    {
        return WxConfig::PAY_BANK_URL;
    }

    /**
     * 微信退款接口，需要用到相关加密文件及证书，需要重新进行curl的设置
     * @param string $xml
     * @param string $url
     * @return array
     *
     */
    protected function curlPost($xml, $url)
    {
        $curl = new Curl();
        $responseTxt = $curl->set([
            'CURLOPT_HEADER' => 0,
            'CURLOPT_SSL_VERIFYHOST' => false,
            'CURLOPT_SSLCERTTYPE' => 'PEM', //默认支持的证书的类型，可以注释
            'CURLOPT_SSLCERT' => $this->config->appCertPem,
            'CURLOPT_SSLKEY' => $this->config->appKeyPem,
            'CURLOPT_CAINFO' => $this->config->cacertPath,
        ])->post($xml)->submit($url);

        return $responseTxt;
    }

    /**
     * 转款的返回数据
     * @param array $ret
     * @return mixed
     */
    protected function retData(array $ret)
    {
        if ($this->config->returnRaw) {
            $ret['channel'] = Config::WX_PAY_BANK;
            return $ret;
        }

        // 请求失败，可能是网络
        if ($ret['return_code'] != 'SUCCESS') {
            return $retData = [
                'is_success' => 'F',
                'error' => $ret['return_msg'],
                'channel' => Config::WX_PAY_BANK,
            ];
        }

        // 业务失败
        if ($ret['result_code'] != 'SUCCESS') {
            return $retData = [
                'is_success' => 'F',
                'error_code' => $ret['err_code'] ?? '',
                'error' => $ret['err_code_des'] ?? '',
                'channel' => Config::WX_PAY_BANK,
            ];
        }

        return $this->createBackData($ret);
    }

    /**
     * 返回数据
     * @param array $data
     * @return array
     * @createTime 2019/10/10 14:35
     */
    protected function createBackData(array $data)
    {
        $retData = [
            'is_success' => 'T',
            'response' => [
                'trans_no' => $data['partner_trade_no'], //商户企业付款单号
                'transaction_id' => $data['payment_no'], //微信企业付款单号（代付成功后，返回的内部业务单号）
                'amount' => bcdiv($data['amount'], 100, 2), //代付金额，单位：分。为了保持一致性，故此转为元
                'fee' => bcdiv($data['cmms_amt'], 100, 2), //手续费金额，单位：分。为了保持一致性，故此转为元
                'pay_date' => $data['payment_time'] ?? date('Y-m-d H:i:s'), //微信企业付款到银行卡接口无付款成功时间字段
                'channel' => Config::WX_PAY_BANK,
            ],
        ];

        return $retData;
    }

    /**
     * 企业付款，不需要签名
     * @param array $retData
     * @return bool
     */
    protected function verifySign(array $retData)
    {
        return true;
    }

    /**
     * @param array $data
     *
     * @return array|string
     * @throws PayException
     */
    public function handle(array $data)
    {
        $buildClass = $this->getBuildDataClass();

        try {
            $this->reqData = new $buildClass($this->config, $data);
        } catch (PayException $e) {
            throw $e;
        }

        //企业付款到银行卡参数不能进行urldecode
        $this->reqData->setSign(false);

        $xml = DataParser::toXml($this->reqData->getData());
        $ret = $this->sendReq($xml);

        // 检查返回的数据是否被篡改
        $flag = $this->verifySign($ret);
        if (!$flag) throw new PayException('微信返回数据被篡改。请检查网络是否安全！');

        return $this->retData($ret);
    }

}
